import os
import sys
import time
import math
import uuid
import pymysql
import requests
import argparse
from bs4 import BeautifulSoup
from datetime import datetime
from fake_useragent import UserAgent
from pymysql.cursors import DictCursor


current_task_uuid = str(uuid.uuid4())
def check_and_create_directory(directory_name):
    directory_name +='_'+current_task_uuid
    current_directory = os.getcwd()
    target_directory = os.path.join(current_directory, directory_name)

    if not os.path.exists(target_directory):
        os.makedirs(target_directory)
        print(f"目录 '{directory_name}' 创建成功！")

    return target_directory


def print_progress_bar(iteration, total, prefix='', suffix='', length=80, fill='█', print_end='\r'):
    percent = ("{0:.1f}").format(100 * (iteration / float(total)))
    filled_length = int(length * iteration // total)
    bar = fill * filled_length + '-' * (length - filled_length)

    sys.stdout.write(f'\r{prefix} |{bar}| {percent}% {suffix}')
    sys.stdout.flush()

    if iteration == total:
        print(print_end)


def get_mysql_connection():
    conn = pymysql.connect(
        host="rm-2zeeh682k7f1q79qwno.mysql.rds.aliyuncs.com", # 数据库主机地址
        port=3306,
        database="scum_log",
        user="root",
        passwd="Acfan0523@gmail"
    )
    return conn



def get_db_data():
    conn = get_mysql_connection()
    cursor = conn.cursor(DictCursor)  # 使用 DictCursor 获取字典类型的结果集
    cursor.execute("SELECT * FROM player WHERE sync_time < DATE_SUB(NOW(), INTERVAL 7 DAY) or last_vac_time is null ")
    rows = cursor.fetchall()
    conn.close()
    return rows

def get_new_player():
    conn = get_mysql_connection()
    cursor = conn.cursor(DictCursor)  # 使用 DictCursor 获取字典类型的结果集
    cursor.execute("SELECT * FROM player where avatar is null or avatar = ''")
    rows = cursor.fetchall()
    conn.close()
    return rows

def get_player_steam_info(player):
    steam_info_base_url = "https://steamcommunity.com/profiles/"

    user_agent = UserAgent().random
    headers = {'User-Agent': user_agent}
    try:
        response = requests.get(steam_info_base_url + str(player['steam_id']), headers=headers)
        response.raise_for_status()

        soup = BeautifulSoup(response.content, 'html.parser')

        avatar_before = soup.select("div.playerAvatarAutoSizeInner img")
        avatar = avatar_before[-1]['src'] if avatar_before else ''

        name = soup.select('span.actual_persona_name')[0].text
        vac_flag, vac_time, vac_num, private_flag, game_duration = 0, '-', 0, 1, 0


        elements = soup.select("div.profile_ban_status")
        if elements:
            element = elements[0]
            vac_flag = 1
            vac_time = element.text.replace("\t",'').replace("\n",'').replace("\r",'')
            profile_ban_info = element.select_one("div")
            if profile_ban_info:
                vac_num = 2 if "Multiple game" in profile_ban_info.text or "多个" in profile_ban_info.text else 1

        recent_games = soup.select("div.recent_game")
        if recent_games:
            private_flag = 0
            for recent_game in recent_games:
                game_names = recent_game.select("div.game_name a")
                if game_names:
                    text = game_names[0].text
                    if text in ["人渣", "SCUM"]:
                        game_info_details = recent_game.select_one("div.game_info_details")
                        if game_info_details:
                            v = float(game_info_details.text.split(" hrs")[0].replace(",", ""))
                            game_duration = round(v)
        player['name'] = name
        player['avatar'] = avatar
        player['vac_flag'] = vac_flag
        player['last_vac_time'] = vac_time
        player['vac_num'] = vac_num
        player['private_flag'] = private_flag
        player['game_duration'] = game_duration
        return player

    except requests.exceptions.RequestException as e:
        print(f"Update player steam info error: {e}")

def assemble_update_sql(player):
    return (
        f"""UPDATE player p SET 
        p.steam_name = '{player['name'].replace("'", "''")}', 
        p.avatar = '{player['avatar'].replace("'", "''")}', 
        vac_flag = {player['vac_flag']}, 
        last_vac_time = '{player['last_vac_time']}', 
        vac_num = {player['vac_num']}, 
        private_flag = {player['private_flag']}, 
        game_duration = {player['game_duration']} 
        WHERE steam_id = {player['steam_id']};"""
    )

def batch_update_with_progress(player_sqls, batch_size):
    conn = get_mysql_connection()
    cursor = conn.cursor()

    try:
        total_batches = (len(player_sqls) + batch_size - 1) // batch_size

        for i in range(0, len(player_sqls), batch_size):
            batch = player_sqls[i:i+batch_size]
            for j, sql in enumerate(batch, start=1):
                cursor.execute(sql)
                print_progress_bar(i + j, len(player_sqls), prefix='RunUpdateSQL:', suffix='Complete')

            # 提交每个批次的更改
            conn.commit()

    except Exception as e:
        # 发生异常时回滚事务
        conn.rollback()
        print(f"Batch update failed: {e}")

    finally:
        cursor.close()
        conn.close()


parser = argparse.ArgumentParser(description='处理玩家信息脚本')
parser.add_argument('-checkNewPlayer', action='store_true', help='检查新玩家')

args = parser.parse_args()



print(f' task begin : ->  current time : {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
players = []
if args.checkNewPlayer:
    players = get_new_player()
else:
    players= get_db_data()
player_sqls = []
total_players = len(players)

try:
    for i, player in enumerate(players):
        player = get_player_steam_info(player)
        print_progress_bar(i + 1, total_players, prefix=f'FromHTTPGetPlayerInfo : {total_players} ', suffix=f'Complete : {i+1}')
except Exception as e:
    print(e)



try:
    for i, player in enumerate(players):
        player_sqls.append(assemble_update_sql(player))
        print_progress_bar(i + 1, total_players, prefix=f'AssmbleSqlData : {total_players} ', suffix=f'Complete : {i+1}')
except Exception as e:
    print(e)

batch_size = 70
if(total_players>0):
    print(f"next split sql total size : {total_players} ")
    print(f"next split sql batch size : {batch_size} ")
    print(f"total split size : {int(math.ceil(total_players/batch_size))}")
    batch_update_with_progress(player_sqls,batch_size)

print(f' task end : ->  current time : {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')

